# -*- coding: utf-8 -*-

from odoo import models, fields, api
from odoo.exceptions import UserError


class CpqBomLine(models.Model):
    _name = 'cpq.bom.line'
    _description = 'BOM明细行'
    _order = 'sequence, id'
    _rec_name = 'part_name'

    bom_id = fields.Many2one(
        'cpq.bom',
        'BOM',
        required=True,
        ondelete='cascade',
        index=True
    )
    sequence = fields.Integer('序号', default=10, required=True)
    
    # ========== 系统生成唯一ID ⭐⭐⭐⭐⭐ ==========
    unique_id = fields.Char(
        '系统唯一ID',
        compute='_compute_unique_id',
        store=True,
        index=True,
        help='格式: MS11-V1-0001 (项目-版本-序号)'
    )
    
    @api.depends('bom_id', 'bom_id.project_id', 'bom_id.project_id.code', 
                 'bom_id.version_number', 'sequence')
    def _compute_unique_id(self):
        """生成系统唯一ID"""
        for line in self:
            if line.bom_id and line.bom_id.project_id:
                project_code = line.bom_id.project_id.code or 'PRJ'
                version = line.bom_id.version_number or 'V1'
                # 序号格式化为4位数字
                seq = str(line.sequence).zfill(4)
                line.unique_id = f'{project_code}-{version}-{seq}'
            else:
                line.unique_id = False
    
    # ========== 零件标识 ==========
    part_number = fields.Char(
        '零件号',
        index=True,
        help='客户零件号，允许为空或XX'
    )
    
    part_name = fields.Char(
        '零件名称',
        required=True,
        index=True
    )
    
    level = fields.Char(
        '层级',
        help='L1/L2/L3 或 1.1.1 格式'
    )
    
    level_depth = fields.Integer(
        '层级深度',
        compute='_compute_level_depth',
        store=True,
        help='1=一级件，2=二级件，3=三级件'
    )
    
    @api.depends('level')
    def _compute_level_depth(self):
        """计算层级深度"""
        for line in self:
            if not line.level:
                line.level_depth = 1
            elif line.level.startswith('L'):
                # L1, L2, L3格式
                try:
                    line.level_depth = int(line.level[1:])
                except:
                    line.level_depth = 1
            else:
                # 1.1.1格式
                parts = str(line.level).split('.')
                line.level_depth = len(parts)
    
    # ========== 版本对比字段 ⭐⭐⭐⭐⭐ ==========
    change_type = fields.Selection([
        ('none', '无变化'),
        ('new', '新增'),
        ('delete', '删除'),
        ('modify', '修改')
    ], string='变化类型', default='none', index=True)
    
    previous_line_id = fields.Many2one(
        'cpq.bom.line',
        '原版本行',
        help='对比时关联的原版本BOM行'
    )
    
    change_fields = fields.Char(
        '变化字段',
        help='记录哪些字段变化了，如: weight,material,process'
    )
    
    change_details = fields.Text(
        '变化明细',
        compute='_compute_change_details',
        help='详细的变化信息'
    )
    
    @api.depends('change_type', 'change_fields', 'previous_line_id')
    def _compute_change_details(self):
        """计算变化明细"""
        for line in self:
            if line.change_type == 'none':
                line.change_details = ''
            elif line.change_type == 'new':
                line.change_details = '新增零件'
            elif line.change_type == 'delete':
                line.change_details = '已删除'
            elif line.change_type == 'modify' and line.previous_line_id:
                # 显示具体变化
                details = []
                if 'weight' in (line.change_fields or ''):
                    old_weight = line.previous_line_id.weight or 0
                    new_weight = line.weight or 0
                    details.append(f'克重: {old_weight}g → {new_weight}g')
                if 'material' in (line.change_fields or ''):
                    old_material = line.previous_line_id.material or ''
                    new_material = line.material or ''
                    details.append(f'材料: {old_material} → {new_material}')
                if 'process' in (line.change_fields or ''):
                    old_process = line.previous_line_id.process or ''
                    new_process = line.process or ''
                    details.append(f'工艺: {old_process} → {new_process}')
                line.change_details = '; '.join(details) if details else '参数已修改'
            else:
                line.change_details = ''
    
    # ========== 关键参数（影响成本）⭐ ==========
    weight = fields.Float('克重(g)', digits=(16, 3), help='零件重量，单位：克')
    material = fields.Char('材料', help='如：PP, PPE, PC+ABS')
    process = fields.Char('工艺', help='如：注塑, 喷涂, 注塑+喷涂')
    surface_area = fields.Float('表面积(dm²)', digits=(16, 2), help='喷涂面积')
    thickness = fields.Float('厚度(mm)', digits=(16, 2))
    color = fields.Char('颜色')
    
    # ========== 制造属性 ⭐ ==========
    make_or_buy = fields.Selection([
        ('L', '自制'),
        ('P', '外采')
    ], string='自制/外采', required=True, default='L')
    
    process_type = fields.Selection([
        ('injection', '注塑'),
        ('painting', '喷涂'),
        ('injection_painting', '注塑+喷涂'),
        ('injection_painting_assembly', '注塑+喷涂+装配'),
        ('assembly', '装配'),
        ('outsource', '外协')
    ], string='工艺类型')
    
    # ========== 数量 ==========
    quantity = fields.Float('数量', default=1.0, digits=(16, 3))
    uom_id = fields.Many2one('cpq.uom', '单位', default=lambda self: self._get_default_uom())
    
    @api.model
    def _get_default_uom(self):
        """获取默认单位（件）"""
        uom = self.env['cpq.uom'].search([('code', '=', 'PCS')], limit=1)
        if not uom:
            # 如果没有件，返回第一个单位
            uom = self.env['cpq.uom'].search([], limit=1)
        return uom.id if uom else False
    
    # ========== 成本相关 ⭐ ==========
    unit_cost = fields.Monetary(
        '单件成本',
        compute='_compute_cost',
        store=True,
        currency_field='currency_id',
        help='单件成本（不含分摊）'
    )
    
    cost_formula_id = fields.Many2one(
        'cpq.cost.formula',
        '成本公式',
        help='使用的成本计算公式'
    )
    
    # 成本参数JSON存储
    cost_params = fields.Text(
        '成本参数',
        help='JSON格式存储计算参数'
    )
    
    # 采购价（外采件）
    purchase_price = fields.Monetary(
        '采购价',
        currency_field='currency_id',
        help='外采件采购价格'
    )
    
    # 分摊成本（一级件）
    amortization_cost = fields.Monetary(
        '分摊成本',
        currency_field='currency_id',
        help='投资分摊到该零件的成本'
    )
    
    # 总成本
    total_cost = fields.Monetary(
        '总成本',
        compute='_compute_total_cost',
        store=True,
        currency_field='currency_id',
        help='总成本 = 单件成本 + 分摊成本'
    )
    
    currency_id = fields.Many2one(
        'cpq.currency',
        '货币',
        related='bom_id.project_id.currency_id',
        store=True
    )
    
    # ========== 备注 ==========
    notes = fields.Text('备注')
    
    @api.depends('make_or_buy', 'purchase_price', 'unit_cost')
    def _compute_cost(self):
        """计算单件成本（简化版，后续完善）"""
        for line in self:
            if line.make_or_buy == 'P':
                # 外采件：使用采购价
                line.unit_cost = line.purchase_price or 0.0
            else:
                # 自制件：后续通过公式计算
                # TODO: 实现公式计算逻辑
                line.unit_cost = 0.0
    
    @api.depends('unit_cost', 'amortization_cost')
    def _compute_total_cost(self):
        """计算总成本"""
        for line in self:
            line.total_cost = (line.unit_cost or 0.0) + (line.amortization_cost or 0.0)

